package com.zhoug.player3.tx;

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;


import com.tencent.rtmp.ITXLivePlayListener;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXLivePlayConfig;
import com.tencent.rtmp.TXLivePlayer;
import com.tencent.thumbplayer.tmediacodec.util.LogUtils;
import com.tencent.ugc.TXRecordCommon;
import com.zhoug.player3.core.BasePlayer;
import com.zhoug.player3.core.PlayError;
import com.zhoug.player3.core.ui.VideoRatioTextureView;
import com.zhoug.player3.core.utils.PlayUrlUtils;

import androidx.annotation.Nullable;

import static com.tencent.rtmp.TXLiveConstants.PLAY_ERR_NET_DISCONNECT;
import static com.tencent.rtmp.TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION;
import static com.tencent.rtmp.TXLiveConstants.PLAY_EVT_CONNECT_SUCC;
import static com.tencent.rtmp.TXLiveConstants.PLAY_EVT_PLAY_BEGIN;
import static com.tencent.rtmp.TXLiveConstants.PLAY_EVT_PLAY_END;
import static com.tencent.rtmp.TXLiveConstants.PLAY_EVT_PLAY_LOADING;
import static com.tencent.rtmp.TXLiveConstants.PLAY_EVT_PLAY_PROGRESS;
import static com.tencent.rtmp.TXLiveConstants.PLAY_EVT_VOD_PLAY_PREPARED;
import static com.tencent.rtmp.TXLiveConstants.PLAY_WARNING_RECONNECT;
import static com.tencent.rtmp.TXLiveConstants.PLAY_WARNING_VIDEO_PLAY_LAG;
import static com.tencent.rtmp.TXLiveConstants.PUSH_ERR_AUDIO_ENCODE_FAIL;
import static com.tencent.rtmp.TXLiveConstants.PUSH_ERR_NET_DISCONNECT;
import static com.tencent.rtmp.TXLiveConstants.PUSH_ERR_UNSUPPORTED_RESOLUTION;
import static com.tencent.rtmp.TXLiveConstants.PUSH_ERR_VIDEO_ENCODE_FAIL;

/**
 * @Author: zhoug
 * @Date: 2023/1/11
 * @Description:
 */
public class TxPlayerHelper extends BasePlayer {
    private static final String TAG = ">>>TXLivePlayerHelper";
    private TXLivePlayer mPlayer;
    private Surface mSurface;
    private long mDuration = Long.MIN_VALUE;

    public TxPlayerHelper() {

    }

    public TxPlayerHelper(Context context) {
        mContext = context;
    }

    /**
     * 始化播放器
     */
    private synchronized void initPlayer() {
        if (mPlayer != null) {
            LogUtils.d(TAG, "initPlayer:无需重复初始化播放器");
            return;
        }
        LogUtils.d(TAG, "initPlayer:初始化播放器");
        TXLivePlayConfig config = new TXLivePlayConfig();
        config.setCacheTime(1);//设置播放器缓存时间，单位为秒；默认值为5秒。 不建议设置过大，会影响秒开以及直播流播放的实时性
        config.setAutoAdjustCacheTime(true);//SDK 将根据网络状况在一个范围内调整缓存时间
        config.setMinAutoAdjustCacheTime(1);
        config.setMaxAutoAdjustCacheTime(3);
        config.setConnectRetryCount(3);
        mPlayer = new TXLivePlayer(mContext);
        mPlayer.enableHardwareDecode(true);//启用视频硬解码
        mPlayer.setConfig(config);
        _setMute(mMute);
//        _setRenderMode();
        mPlayer.setPlayListener(mITXLivePlayListener);//播放监听器
        mPlayer.setVideoRecordListener(mITXVideoRecordListener);//录像监听
        _setTextureView();
    }

    /**
     * 播放监听器
     */
    private ITXLivePlayListener mITXLivePlayListener = new ITXLivePlayListener() {
        @Override
        public void onPlayEvent(int i, Bundle bundle) {
           /* if (debug) {
                LogUtils.d(TAG, "onPlayEvent:code="+i);
            }*/
            switch (i) {
                case PLAY_WARNING_VIDEO_PLAY_LAG:
                    LogUtils.w(TAG, "onPlayEvent:卡顿");
                    break;
                case PUSH_ERR_VIDEO_ENCODE_FAIL:
                    LogUtils.e(TAG, "onPlayEvent:视频编码失败");
                    callError(PlayError.VIDEO_ENCODE_FAIL, "视频编码失败");
                    break;
                case PUSH_ERR_AUDIO_ENCODE_FAIL:
                    LogUtils.e(TAG, "onPlayEvent:音频编码失败");
                    callError(PlayError.AUDIO_ENCODE_FAIL, "音频编码失败");
                    break;
                case PUSH_ERR_UNSUPPORTED_RESOLUTION:
                    LogUtils.e(TAG, "onPlayEvent:不支持的视频分辨率");
                    callError(PlayError.UNSUPPORTED_RESOLUTION, "不支持的视频分辨率");

                case PLAY_WARNING_RECONNECT:
                    LogUtils.e(TAG, "onPlayEvent:重连");
                    break;
                case PLAY_ERR_NET_DISCONNECT:
                    LogUtils.d(TAG, "连接失败");
                    callError(PlayError.NETWORK_CONNECTION_FAILED, "网络连接失败");
                    break;
                case PUSH_ERR_NET_DISCONNECT:
                    LogUtils.e(TAG, "onPlayEvent:网络断连，且经三次重连无效，更多重试请自行重启推流");
                    callError(PlayError.NETWORK_CONNECTION_FAILED, "网络连接失败");
                    break;
                case PLAY_EVT_PLAY_LOADING:
                    LogUtils.d(TAG, "onPlayEvent:加载中");
                    break;
                case PLAY_EVT_VOD_PLAY_PREPARED:
                    LogUtils.d(TAG, "onPlayEvent:准备好了");
//                    startPlayTime
                    callStatusChange(STATE_PLAYING);
                    break;
                case PLAY_EVT_PLAY_BEGIN:
                    callStatusChange(STATE_PLAYING);
                    break;
                case PLAY_EVT_PLAY_END:
                    callStatusChange(STATE_ENDED);
                    LogUtils.d(TAG, "onPlayEvent:播放完了");
                    break;
                case PLAY_EVT_CONNECT_SUCC:
                    LogUtils.d(TAG, "onPlayEvent:连接成功");
                    break;
                case PLAY_EVT_PLAY_PROGRESS://播放进度更新
//                    LogUtils.d(TAG, "onPlayEvent:播放进度更新"+bundle);
                    if (mOnPlayProgressListener != null && bundle != null) {
                        long duration = bundle.getInt(TXLiveConstants.EVT_PLAY_DURATION_MS);
                        long position = bundle.getInt(TXLiveConstants.EVT_PLAY_PROGRESS) * 1000;
                        if (mDuration != duration) {
                            mDuration = duration;
                            mOnPlayProgressListener.onDurationChange(duration);
                        }
                        mOnPlayProgressListener.onPositionChange(position);
                    }
                    break;
                case PLAY_EVT_CHANGE_RESOLUTION:
                    LogUtils.d(TAG, "onPlayEvent:分辨率改变:");
                    if (bundle != null) {
                        int width = bundle.getInt(TXLiveConstants.EVT_PARAM1);
                        int height = bundle.getInt(TXLiveConstants.EVT_PARAM2);
                        if (mOnPlayListener != null) {
                            mOnPlayListener.onVideoSizeChanged(width, height);
                        }
                        if (mTextureView instanceof VideoRatioTextureView) {
                            ((VideoRatioTextureView) mTextureView).setRatio(width * 1.0f / height);
                        }
                    }
                    break;

            }
        }

        @Override
        public void onNetStatus(Bundle bundle) {

        }
    };

    /**
     * 视频录制监听
     */
    private TXRecordCommon.ITXVideoRecordListener mITXVideoRecordListener = new TXRecordCommon.ITXVideoRecordListener() {
        @Override
        public void onRecordEvent(int i, Bundle bundle) {
            LogUtils.d(TAG, "onRecordEvent:i:" + i);
        }

        @Override
        public void onRecordProgress(long l) {
            LogUtils.d(TAG, "onRecordEvent:l:" + l);

        }

        @Override
        public void onRecordComplete(TXRecordCommon.TXRecordResult txRecordResult) {
            if (txRecordResult != null) {
                LogUtils.d(TAG, "onRecordEvent:txRecordResult:"
                        + ",coverPath:" + txRecordResult.coverPath
                        + ",videoPath:" + txRecordResult.videoPath
                        + ",descMsg:" + txRecordResult.descMsg
                );
            } else {
                LogUtils.d(TAG, "onRecordComplete:txRecordResult is null");
            }
        }
    };


    private void setSurface( ) {
        if (mPlayer != null) {
            LogUtils.d(TAG, "设置画面");
            try {
                mPlayer.setSurface(mSurface);
            } catch (Exception e) {
                e.printStackTrace();
                LogUtils.e(TAG, "onSurfaceTextureAvailable:" + e.getMessage());
            }
        }

    }

    /**
     * TextureView SurfaceTextureListener
     */
    private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
            LogUtils.d(TAG, "onSurfaceTextureAvailable:");
            mSurface = new Surface(surfaceTexture);
            setSurface();

        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            Log.d(TAG, "onSurfaceTextureDestroyed:");
            mSurface = null;
            setSurface();
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {

        }
    };

    private void _setTextureView() {
        if (mTextureView != null) {
            mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
            mTextureView.setKeepScreenOn(true);//保持亮屏
            SurfaceTexture surfaceTexture = mTextureView.isAvailable() ? mTextureView.getSurfaceTexture() : null;
            if (surfaceTexture != null) {
                mSurface = new Surface(surfaceTexture);
                setSurface();
            }
        }else{
            mSurface = null;
            setSurface();
        }
    }

    private void _setMute(boolean mute) {
        if (mPlayer != null) {
            mPlayer.setMute(mute);//静音
        }
    }

    /**
     * 感觉无效
     */
    @Deprecated
    private void _setRenderMode() {
        if (mPlayer != null) {
            if (mRenderMode == RENDER_MODE_ADJUST_RESOLUTION) {
                mPlayer.setRenderMode(TXLiveConstants.RENDER_MODE_ADJUST_RESOLUTION);
            } else if (mRenderMode == RENDER_MODE_FULL_FILL_SCREEN) {
                mPlayer.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN);
            }
        }
    }

    /**
     * 设置显示页面
     *
     * @param textureView
     */
    @Override
    public void setVideoTextureView(@Nullable TextureView textureView) {
        super.setVideoTextureView(textureView);
        _setTextureView();
    }

    @Override
    public void setRenderMode(int renderMode) {
        super.setRenderMode(renderMode);
//        _setRenderMode();
    }


    /**
     * 设置静音
     *
     * @param mute true:静音,false:非静音
     */
    @Override
    public void setMute(boolean mute) {
        super.setMute(mute);
        _setMute(mute);
    }

    /**
     * 开始播放,每次都是重新加载资源播放,可以播放新的url
     */
    @Override
    public void startPlay() {
        if (TextUtils.isEmpty(mPlayUrl)) {
            callError(PlayError.URL_IS_EMPTY, "playUrl为空");
            return;
        }
        if (mPlayer == null) {
            initPlayer();
            if (mPlayer == null) {
                callError(PlayError.PLAYER_INIT_FAILURE, "初始化播放器失败");
                return;
            }
        } else {
            try {
                mPlayer.stopPlay(false);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        try {
            int playType = TXLivePlayer.PLAY_TYPE_VOD_HLS;
            int type = PlayUrlUtils.getUrlType(mPlayUrl);
            if (type == PlayUrlUtils.TYPE_RTSP || type == PlayUrlUtils.TYPE_RTMP) {
                playType = TXLivePlayer.PLAY_TYPE_LIVE_RTMP;
                LogUtils.d(TAG, "startPlay:RTMP");
            } else if (type == PlayUrlUtils.TYPE_FLV) {
                playType = TXLivePlayer.PLAY_TYPE_LIVE_FLV;
                LogUtils.d(TAG, "startPlay:FLV");
            }
            int success = mPlayer.startPlay(mPlayUrl, playType);
            if (success == 0) {
                LogUtils.d(TAG, "startPlay:成功启动播放");
                callStatusChange(STATE_START);
            } else if (success == -1) {
                LogUtils.e(TAG, "startPlay:播放失败，playUrl为空");
                callError(PlayError.URL_IS_EMPTY, "playUrl为空");
            } else if (success == -2) {
                LogUtils.e(TAG, "startPlay:播放失败，playUrl非法");
                callError(PlayError.URL_IS_ILLEGAL, "playUrl非法:" + mPlayer);

            } else if (success == -3) {
                LogUtils.e(TAG, "startPlay:播放失败，playType非法");
                callError(PlayError.URL_IS_ILLEGAL, "playUrl非法:" + mPlayer);
            } else {
                LogUtils.e(TAG, "startPlay:播放失败,未知错误");
                callError(PlayError.UNKNOWN_ERROR, "未知错误");
            }

        } catch (Exception e) {
            e.printStackTrace();
            callError(PlayError.UNKNOWN_ERROR, "发生错误:" + e.getMessage());
        }


    }


    /**
     * 停止播放,会释放加载的媒体和资源
     */
    @Override
    public void stopPlay() {
        try {
            if (mPlayer != null) {
                mPlayer.stopPlay(false);
                LogUtils.d(TAG, "stopPlay:停止播放");
            }
            callStatusChange(STATE_IDLE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 如果正在播放则暂停播放,否则调用{@link #stopPlay()}停止播放
     */
    @Override
    public void pausePlay() {
        try {
            if (mPlayer != null) {
                if (mPlayer.isPlaying()) {
                    mPlayer.pause();
                    LogUtils.d(TAG, "stopPlay:暂停");
                    callStatusChange(STATE_PAUSE);
                } else {
                    stopPlay();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 如果暂停了或者资源已经准备好了则播放,否则{@link #startPlay()}重新开始播放
     */
    @Override
    public void resumePlay() {
        try {
            if (mPlayer != null) {
                if (mPlayState == STATE_PAUSE) {
                    mPlayer.resume();
                    LogUtils.d(TAG, "stopPlay:恢复播放");
                    callStatusChange(STATE_PLAYING);
                } else {
                    startPlay();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 设置指定位置播放
     *
     * @param positionMs
     */
    @Override
    public void seekTo(long positionMs) {
        if (mPlayer != null) {
            mPlayer.seek((int) (positionMs / 1000));
        }
    }

    /**
     * 切换为直播
     */
    @Override
    public void switchToLive() {

    }

    /**
     * 释放资源,注意请把所有setXXX的数据设置为空
     */
    @Override
    public void release() {
        super.release();
        try {
            if (mPlayer != null) {
                mPlayer.stopPlay(true);
                LogUtils.d(TAG, "stopPlay:停止播放");
            }
            callStatusChange(STATE_IDLE);

            mPlayer = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 开始录制视频
     *
     * @param path 保存的视频地址
     */
    @Override
    public void startRecordVideo(String path) {
        LogUtils.e(TAG, "startRecordVideo:未实现视频录制");
        /*if(mPlayer!=null){
            int success = mPlayer.startRecord(TXRecordCommon.RECORD_TYPE_STREAM_SOURCE);
            if (success != 0) {
                callRecordVideoError("录制视频失败");
            }else{
                callRecordVideoStart();
            }
        }*/

    }

    /**
     * 停止录制视频
     */
    @Override
    public void stopRecordVideo() {
        LogUtils.e(TAG, "startRecordVideo:未实现视频录制");
        /*if(mPlayer!=null){
            int success = mPlayer.stopRecord();
            if (success != 0) {
                callRecordVideoError("停止视频录制失败");
            }
        }*/
    }


    /**
     * 开启对讲
     */
    @Override
    public void startVoiceTalk() {

    }

    /**
     * 停止对讲
     */
    @Override
    public void stopVoiceTalk() {

    }

    /**
     * 是否正在对讲
     *
     * @return
     */
    @Override
    public boolean isTalking() {
        return false;
    }
}
